#pragma once
#include "asr.hpp"
#include "speech.pb.h"
#include "etcd.hpp"

#include <brpc/server.h>

class SpeechServiceImpl : public chat_system::SpeechService
{
public:
    using ptr = std::shared_ptr<SpeechServiceImpl>;
    SpeechServiceImpl(const ASRClient::ptr& asr_client)
        : _asr_client(asr_client)
    {}
    virtual void SpeechRecognition(google::protobuf::RpcController* controller,
                                   const chat_system::SpeechRecognitionReq* request,
                                   chat_system::SpeechRecognitionRsp* response,
                                   google::protobuf::Closure* done)
    {
        LOG_DEBUG("收到语音转文字请求");
        brpc::ClosureGuard rpc_guard(done);
        std::string speech_data = request->speech_content();
        std::string err_msg;
        std::string result = _asr_client->recognize(speech_data, err_msg);
        response->set_request_id(request->request_id());
        if(result.empty())
        {
            LOG_ERROR("语音识别失败!");
            response->set_success(false);
            response->set_errmsg("语音识别失败!" + err_msg);
            return;
        }
        LOG_INFO("{}号用户语音识别成功: {}",request->request_id(), result);
        response->set_success(true);
        response->set_recognition_result(result);
        return;
    }   

private:
    // 语音识别客户端
    ASRClient::ptr _asr_client;
};


class SpeechServer
{
public:
    using ptr = std::shared_ptr<SpeechServer>;
    SpeechServer(SpeechServiceImpl::ptr speech_service_impl,
                 Registry::ptr registry_client,
                 std::shared_ptr<brpc::Server> server)
        : _speech_service_impl(speech_service_impl)
        , _registry_client(registry_client)
        , _server(server)
    {}
    void start()
    {
        LOG_INFO("语音服务已启动");
        _server->RunUntilAskedToQuit();
    }
private:
    SpeechServiceImpl::ptr _speech_service_impl;
    Registry::ptr _registry_client;
    std::shared_ptr<brpc::Server> _server;
};


//用来创建SpeechServer的构建器
class SpeechServerBuilder
{
public:
    void make_asr_object(const std::string app_id, const std::string &ak, const std::string &sk)
    {
        ASRClient::ptr asr_client = std::make_shared<ASRClient>(app_id, ak, sk);
        _speech_service_impl = std::make_shared<SpeechServiceImpl>(asr_client);
    }
    void make_reg_object(const std::string &etcd_host, const std::string& service_name, const std::string service_host)
    {
        _registry_client = std::make_shared<Registry>(etcd_host);
        bool success = _registry_client->registry(service_name, service_host);
        if(!success)
        {
            LOG_ERROR("注册服务到etcd失败");
            return;
        }
        LOG_INFO("注册服务{} - {}到etcd成功", service_name, service_host);
    }
    void make_rpc_object(uint16_t port, int32_t timeout, uint8_t num_threads)
    {
        logging::LoggingSettings tmp_log;
        tmp_log.logging_dest = logging::LOG_TO_NONE;
        logging::InitLogging(tmp_log);
        _server = std::make_shared<brpc::Server>();
        int ret = _server->AddService(_speech_service_impl.get(), brpc::SERVER_DOESNT_OWN_SERVICE);
        if(ret < 0)
        {
            LOG_ERROR("注册服务失败");
            return;
        }
        brpc::ServerOptions options;
        options.idle_timeout_sec = timeout;
        options.num_threads = num_threads;
        ret = _server->Start(port, &options);
        if(ret < 0)
        {
            LOG_ERROR("启动服务器失败");
            return;  
        }
    }

    SpeechServer::ptr build()
    {
        if(_speech_service_impl == nullptr)
        {
            LOG_ERROR("ASR服务对象未创建");
            return nullptr;
        }
        if(_registry_client == nullptr)
        {
            LOG_ERROR("注册中心对象未创建");
            return nullptr;
        }
        if(_server == nullptr)
        {
            LOG_ERROR("RPC服务器对象未创建");
            return nullptr;
        }
        SpeechServer::ptr speech_server = std::make_shared<SpeechServer>(_speech_service_impl, _registry_client,_server);
        return speech_server;
    }
private:
    SpeechServiceImpl::ptr _speech_service_impl;
    Registry::ptr _registry_client;
    std::shared_ptr<brpc::Server> _server;
};